#include "gpio_stm32l4xx.h"

static GPIO_TypeDef* g_GPIOx[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI};
static uint16_t g_PINx[] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5,
                            GPIO_PIN_6, GPIO_PIN_7, GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10,
                            GPIO_PIN_11, GPIO_PIN_12, GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15};
static uint16_t g_IRQn_Pin[] = {EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
                              EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn,
                              EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, 
                              EXTI15_10_IRQn, EXTI15_10_IRQn};
typedef struct irq_handle
{
    GpioIrqFunc irqHandler; /* 中断处理函数 */
    void *userParam; /* 中断处理函数参数 */
} irq_handle_def;

irq_handle_def g_FuncVect[16];

static struct Stm32L4xxGpioCntlr g_stm32xx = {
    .groups = NULL,
    .groupNum = STM32L4_GROUP_MAX,
    .bitNum = STM32L4_BIT_MAX,
    .pinCount = STM32L4_PIN_MAX,
};
static inline struct Stm32L4xxGpioCntlr *ToStm32L4xxGpioCntlr(struct GpioCntlr *cntlr)
{
    return (struct Stm32L4xxGpioCntlr *)cntlr;
}

static inline uint16_t Stm32L4xxToGroupNum(uint16_t gpio)
{
    return (uint16_t)(gpio / g_stm32xx.bitNum);
}

static inline uint16_t Stm32L4xxToBitNum(uint16_t gpio)
{
    return (uint16_t)(gpio % g_stm32xx.bitNum);
}

static inline uint16_t Stm32L4xxToGpioNum(uint16_t group, uint16_t bit)
{
    return (uint16_t)(group * g_stm32xx.bitNum + bit);
}

static int32_t  Stm32L4xxGpioCheck(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *gNum, uint16_t *bitNum)
{
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    if (cntlr == NULL || cntlr->priv == NULL) {
        printf("%s: cntlr or priv is NULL\n", __func__);
        return HDF_ERR_INVALID_OBJECT;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    *gNum = Stm32L4xxToGroupNum(gpio);
    *bitNum = Stm32L4xxToBitNum(gpio);
    // printf("*gNum:%d\n",*gNum);
    if (gpio >= stm32xx->pinCount || *gNum >= stm32xx->groupNum) {
        printf("%s: err gpio:%u or group index:%u\n", __func__, gpio, *gNum);
        return HDF_ERR_INVALID_PARAM;
    }
    return HDF_SUCCESS;
}
////=======中断处理函数，由于nvic已经命名好了中断函数名，只能这么定义了
void UserDefine_GPIO_EXTI_IRQHandler(uint16_t bitbum)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(g_PINx[bitbum]) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(g_PINx[bitbum]);
    if(g_FuncVect[bitbum].irqHandler != NULL) {
        g_FuncVect[bitbum].irqHandler(116,NULL);
    }    
    HAL_GPIO_EXTI_Callback(g_PINx[bitbum]);
  }
}

void EXTI0_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(0);
}

void EXTI1_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(1);
}

void EXTI2_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(2);
}

void EXTI3_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(3);
}

void EXTI4_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(4);
}

void EXTI9_5_IRQHandler()
{
  UserDefine_GPIO_EXTI_IRQHandler(5);
  UserDefine_GPIO_EXTI_IRQHandler(6);
  UserDefine_GPIO_EXTI_IRQHandler(7);
  UserDefine_GPIO_EXTI_IRQHandler(8);
  UserDefine_GPIO_EXTI_IRQHandler(9);
}

void EXTI15_10_IRQHandler(void)
{
  UserDefine_GPIO_EXTI_IRQHandler(10);
  UserDefine_GPIO_EXTI_IRQHandler(11);
  UserDefine_GPIO_EXTI_IRQHandler(12);
  UserDefine_GPIO_EXTI_IRQHandler(13);
  UserDefine_GPIO_EXTI_IRQHandler(14);
  UserDefine_GPIO_EXTI_IRQHandler(15);
}
////=======中断 over
static int32_t GpioMethodrequest(struct GpioCntlr *cntlr, uint16_t gpio) 
{
    int32_t ret;
    uint16_t gNum;
    uint16_t bitNum;
    struct Stm32L4xxGpioCntlr *stm32xx;
    struct Stm32L4xxGpioGroup *group;

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];

    /* 置为0 */
    printf("request before:stm32xx:%x,cntlr:%x  pinDir:%x,pinInitFlag:%x\n", stm32xx, cntlr, group->pinDir, group->pinInitFlag);
    group->pinDir &= ~(1<<bitNum);
    group->pinInitFlag &= ~(1<<bitNum);  
    printf("pinDir:%x,pinInitFlag:%x\n", group->pinDir, group->pinInitFlag);
    // 时钟初始化
    switch (gNum) {
    case 0:
        __HAL_RCC_GPIOA_CLK_ENABLE();
        break;
    case 1:
        __HAL_RCC_GPIOB_CLK_ENABLE();
        printf("HAL_RCC_GPIOB_CLK_ENABLE\n");
        break;
    case 2:
        __HAL_RCC_GPIOC_CLK_ENABLE();
        break;
    case 3:
        __HAL_RCC_GPIOD_CLK_ENABLE();
        break;
    case 4:
        __HAL_RCC_GPIOE_CLK_ENABLE();
        break;
    case 5:
        __HAL_RCC_GPIOF_CLK_ENABLE();
        break;
    case 6:
        __HAL_RCC_GPIOG_CLK_ENABLE();
        break;
    case 7:
        __HAL_RCC_GPIOH_CLK_ENABLE();
        printf("HAL_RCC_GPIOH_CLK_ENABLE\n");
        break;
    case 8:
        __HAL_RCC_GPIOI_CLK_ENABLE();
        break;
    
    default:
        return HDF_FAILURE;
        break;
    }
    return HDF_SUCCESS;
}

static int32_t GpioMethodrelease(struct GpioCntlr *cntlr, uint16_t gpio)
{
    int32_t ret;
    uint16_t gNum;
    uint16_t bitNum;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];
    /* 置为0 */
    group->pinDir &= ~(1<<bitNum);
    group->pinInitFlag &= ~(1<<bitNum);   
    printf("pinDir:%x,pinInitFlag:%x\n", group->pinDir, group->pinInitFlag);

    //时钟释放不应该由这个函数释放，否则会影响其他引脚的时钟
   
    return HDF_SUCCESS;
}


static int32_t GpioMethodSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
{
    /*更改参数列表，并重新初始化*/
    int32_t ret;
    uint32_t irqSave;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    GpioMethodrequest(cntlr,gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];
    printf("%s: gNum:%u,bitNum:%u dir:%u\n", __func__, gNum, bitNum, dir);   

    if (OsalSpinLockIrqSave(&group->lock, &irqSave) != HDF_SUCCESS) {
        printf("OsalSpinLockIrqSave failed\n");
        return HDF_ERR_DEVICE_BUSY;
    }
    stm32xx->GPIO_InitStruct->Pin = g_PINx[bitNum];
    stm32xx->GPIO_InitStruct->Pull = GPIO_NOPULL;
    stm32xx->GPIO_InitStruct->Alternate = 0;
    if (GPIO_DIR_IN == dir) {
        stm32xx->GPIO_InitStruct->Mode = GPIO_MODE_INPUT;
        group->pinDir &= ~(1<<bitNum);
    } else if (GPIO_DIR_OUT == dir) {
        stm32xx->GPIO_InitStruct->Mode = GPIO_MODE_OUTPUT_PP;
        stm32xx->GPIO_InitStruct->Speed = GPIO_SPEED_FREQ_VERY_HIGH;        
        group->pinDir |= 1<<bitNum;
        printf("outPut\n");
    } else {
        printf("dir is in error mode\n");
        return HDF_FAILURE;
    }
    HAL_GPIO_Init(g_GPIOx[gNum], stm32xx->GPIO_InitStruct);
    printf("GPIO set success\n");
    group->pinInitFlag |= 1<<bitNum;
    // (void)OsalSpinUnlockIrqRestore(&group->lock, &irqSave);
    return HDF_SUCCESS;
}

static int32_t GpioMethodGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
{

    /*这里直接调用参数列表*/
    int32_t ret;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum]; 
    if(group->pinInitFlag & (1<<bitNum)) {
        dir = group->pinDir & (1<<bitNum);
    } else {
        printf("there has no dir been set\n");
        return GPIO_DIR_ERR;
    }
    
    return HDF_SUCCESS;
}

static int32_t GpioMethodWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val)
{
    int32_t ret;
    uint32_t irqSave;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];
    /*需要判断是否初始化了*/
    if(!(group->pinInitFlag & (1<<bitNum))) {
        printf("reinitGPIO %x\n",group->pinInitFlag);
        ret = GpioMethodSetDir(cntlr, gpio, GPIO_DIR_OUT);
        if(ret != HDF_SUCCESS) {
            return ret;
        }
    }
    printf("GPIOx:%x:%x , pin:%x:%x,val:%d\n",GPIOH, g_GPIOx[gNum], GPIO_PIN_4, g_PINx[bitNum], val);
    HAL_GPIO_WritePin(g_GPIOx[gNum], g_PINx[bitNum],val);

    return HDF_SUCCESS;
}

static int32_t GpioMethodRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
{
    int32_t ret;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];
    /*需要判断是否初始化了*/
    if(!(group->pinInitFlag & (1<<bitNum))) {
        ret = GpioMethodSetDir(cntlr, gpio, GPIO_DIR_IN);
        if(ret != HDF_SUCCESS) {
            return ret;
        }
    }

    /*需要判断是否初始化了*/

    *val = HAL_GPIO_ReadPin(g_GPIOx[gNum], g_PINx[bitNum]);
    return HDF_SUCCESS;
}


   
////===================使能中断
static int32_t GpioMethodEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{    
    int32_t ret;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    
    /* 配置 EXTI 中断源 到key1 引脚、配置中断优先级*/
    HAL_NVIC_SetPriority(g_IRQn_Pin[bitNum], 0, 0);
    /* 使能中断 */
    HAL_NVIC_EnableIRQ(g_IRQn_Pin[bitNum]);

    return HDF_SUCCESS;
}
////===================失能中断
static int32_t GpioMethodDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{
    int32_t ret;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    
    HAL_NVIC_DisableIRQ(g_IRQn_Pin[bitNum]);

    return HDF_SUCCESS;
}

////===================设置中断函数
static int32_t GpioMethodSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode,
    GpioIrqFunc func, void *arg)
{
    int32_t ret;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);

    printf("enterinf %s\n",__func__);
    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];

    g_FuncVect[bitNum].irqHandler = func;
    g_FuncVect[bitNum].userParam = arg;

    GpioMethodrequest(cntlr,gpio);//打开时钟

    stm32xx->GPIO_InitStruct->Pin = g_PINx[bitNum];
    stm32xx->GPIO_InitStruct->Pull = GPIO_NOPULL;
    stm32xx->GPIO_InitStruct->Alternate = 0;
    stm32xx->GPIO_InitStruct->Mode = GPIO_MODE_IT_RISING;
    stm32xx->GPIO_InitStruct->Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    switch (mode) {
    case GPIO_IRQ_TRIGGER_RISING:
        stm32xx->GPIO_InitStruct->Mode = GPIO_MODE_IT_RISING;
        break;
    case GPIO_IRQ_TRIGGER_FALLING:
        stm32xx->GPIO_InitStruct->Mode = GPIO_MODE_IT_FALLING;
        break;
    default:
        printf("mode undefined:only support TRIGGER_RISING/FALLING\n");
        return  HDF_FAILURE;
        break;
    }

    HAL_GPIO_Init(g_GPIOx[gNum], stm32xx->GPIO_InitStruct);
    group->pinDir |= 1<<bitNum;
    group->ITFlag |= 1<<bitNum;
    printf("GPIO set success\n");
    // (void)OsalSpinUnlockIrqRestore(&group->lock, &irqSave);
    return HDF_SUCCESS;

}

////===================取消中断函数
static int32_t GpioMethodUnsetIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{
    int32_t ret;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;
    struct Stm32L4xxGpioGroup *group = NULL;
    uint16_t gNum;// = Stm32L4xxToGroupNum(gpio);//gpio / g_stm32xx.bitNum
    uint16_t bitNum;// = Stm32L4xxToBitNum(gpio);
    
    ret = Stm32L4xxGpioCheck(cntlr, gpio, &gNum, &bitNum);
    if(ret != HDF_SUCCESS) {
        return ret;
    }
    stm32xx = (struct Stm32L4xxGpioCntlr *)cntlr;
    group = &stm32xx->groups[gNum];

    HAL_GPIO_DeInit(g_GPIOx[gNum], g_PINx[bitNum]);
    group->pinDir &= ~(1<<bitNum);
    group->ITFlag &= ~(1<<bitNum);

    return HDF_SUCCESS;
}






static struct GpioMethod g_method = {
    .request = GpioMethodrequest,//进行时钟调用，并
    .release = GpioMethodrelease,
    .write = GpioMethodWrite,
    .read = GpioMethodRead,
    .setDir = GpioMethodSetDir,
    .getDir = GpioMethodGetDir,
    .toIrq = NULL,//                       // 获取中断号
    .setIrq = GpioMethodSetIrq,         // 设置中断函数
    .unsetIrq = GpioMethodUnsetIrq,     // 取消中断函数
    .enableIrq = GpioMethodEnableIrq,   // 使能中断
    .disableIrq = GpioMethodDisableIrq, // 失能中断
};














static int32_t Stm32L4xxGpioSelfInit(struct Stm32L4xxGpioCntlr *stm32xx)
{
    uint16_t i;
    struct Stm32L4xxGpioGroup *groups = NULL;

    if (stm32xx == NULL) {
        return HDF_ERR_INVALID_PARAM;
    }

    stm32xx->GPIO_InitStruct = (GPIO_InitTypeDef *)OsalMemCalloc(sizeof(stm32xx->GPIO_InitStruct));
    if (stm32xx->GPIO_InitStruct == NULL) {
        return HDF_ERR_MALLOC_FAIL;
    }
    

    groups = (struct Stm32L4xxGpioGroup *)OsalMemCalloc(sizeof(*groups) * stm32xx->groupNum);
    if (groups == NULL) {
        return HDF_ERR_MALLOC_FAIL;
    }
    stm32xx->groups = groups;

    for (i = 0; i < stm32xx->groupNum; i++) {
        groups[i].pinDir = 0;
        groups[i].pinInitFlag = 0;
        groups[i].ITFlag = 0;
        if (OsalSpinInit(&groups[i].lock) != HDF_SUCCESS) {
            goto __ERR__;
        }
    }
    for (i = 0; i < stm32xx->bitNum; i++) {
        g_FuncVect[i].irqHandler = NULL;
        g_FuncVect[i].userParam = NULL;
    }

    printf("pinDir:%x,pinInitFlag:%x\n", groups[7].pinDir, groups[7].pinInitFlag);
    return HDF_SUCCESS;
__ERR__:
    if (groups != NULL) {
        for (; i > 0; i--) {
            (void)OsalSpinDestroy(&groups[i - 1].lock);
        }
        OsalMemFree(groups);
    }
    if (stm32xx->GPIO_InitStruct != NULL) {
        OsalMemFree(stm32xx->GPIO_InitStruct);
        stm32xx->GPIO_InitStruct = NULL;
    }

    return HDF_FAILURE;
}

static void Stm32L4xxGpioSelfRlease(struct Stm32L4xxGpioCntlr *stm32xx)
{
    uint16_t i;

    if (stm32xx == NULL) {
        return;
    }
    if (stm32xx->groups != NULL) {
        for (i = 0; i < stm32xx->groupNum; i++) {
            (void)OsalSpinDestroy(&stm32xx->groups[i].lock);
        }
        OsalMemFree(stm32xx->groups);
        stm32xx->groups = NULL;
    }
    if (stm32xx->GPIO_InitStruct != NULL) {
        OsalMemFree(stm32xx->GPIO_InitStruct);
        stm32xx->GPIO_InitStruct = NULL;
    }
}

static int32_t Stm32L4xxGpioReadDrs(struct Stm32L4xxGpioCntlr *stm32xx, const struct DeviceResourceNode *node)
{
    int32_t ret;
    struct DeviceResourceIface *drsOps = NULL;

    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
    if (drsOps == NULL || drsOps->GetUint16 == NULL || drsOps->GetUint8 == NULL) {
        printf("%s: invalid drs ops fail!\n", __func__);
        return HDF_FAILURE;
    }

    ret = drsOps->GetUint8(node, "groupNum", &stm32xx->groupNum, 0);
    if (ret != HDF_SUCCESS) {
        printf("%s: read groupNum fail!\n", __func__);
        return ret;
    }

    ret = drsOps->GetUint8(node, "bitNum", &stm32xx->bitNum, 0);
    if (ret != HDF_SUCCESS) {
        printf("%s: read bitNum fail!\n", __func__);
        return ret;
    }

    ret = drsOps->GetUint16(node, "pinCount", &stm32xx->pinCount, 0);
    
    if (ret != HDF_SUCCESS) {
        printf("%s: read pinCount fail!\n", __func__);
        return ret;
    }

    return HDF_SUCCESS;
}

static int32_t Stm32L4xxGpioBind(struct HdfDeviceObject *device)
{
    (void)device;
    printf("%s: Enter", __func__);
    return HDF_SUCCESS;
}

static int32_t Stm32L4xxGpioInit(struct HdfDeviceObject *device)
{
    int32_t ret;
    struct Stm32L4xxGpioCntlr *stm32xx = &g_stm32xx;

    printf("%s: Enter\n", __func__);
    if (device == NULL || device->property == NULL) {
        printf("%s: device or property null!\n", __func__);
        return HDF_ERR_INVALID_OBJECT;
    }

    ret = Stm32L4xxGpioReadDrs(stm32xx, device->property);
    if (ret != HDF_SUCCESS) {
        printf("%s: read drs fail:%d\n", __func__, ret);
        return ret;
    }

    if (stm32xx->groupNum > STM32L4_GROUP_MAX || stm32xx->groupNum <= 0 ||
        stm32xx->bitNum > STM32L4_BIT_MAX || stm32xx->bitNum <= 0 ||
        stm32xx->pinCount >= STM32L4_PIN_MAX || stm32xx->pinCount < 0) {
        printf("%s: err groupNum:%u, bitNum:%u,pinCount:%u\n", __func__, stm32xx->groupNum, stm32xx->bitNum, stm32xx->pinCount);
        return HDF_ERR_INVALID_PARAM;
    }

    ret = Stm32L4xxGpioSelfInit(stm32xx);
    if (ret != HDF_SUCCESS) {
        printf("%s: err init cntlr mem:%d\n", __func__, ret);
        return ret;
    }

    stm32xx->cntlr.count = stm32xx->pinCount;
    stm32xx->cntlr.priv = (void *)device->property;
    stm32xx->cntlr.ops = &g_method;
    stm32xx->cntlr.device = device;
    ret = GpioCntlrAdd(&stm32xx->cntlr);
    if (ret != HDF_SUCCESS) {
        printf("%s: err add controller:%d\n", __func__, ret);
        OsalMemFree(stm32xx->GPIO_InitStruct);
        Stm32L4xxGpioSelfRlease(stm32xx);
        return ret;
    }
    printf("%s:stm32xx:%x,cntlr:%x dev service:%s init success!\n", __func__, stm32xx, &stm32xx->cntlr, HdfDeviceGetServiceName(device));
    return HDF_SUCCESS;
}

static void Stm32L4xxGpioRelease(struct HdfDeviceObject *device)
{
    struct GpioCntlr *cntlr = NULL;
    struct Stm32L4xxGpioCntlr *stm32xx = NULL;

    if (device == NULL) {
        printf("%s: device is null!\n", __func__);
        return;
    }

    cntlr = GpioCntlrFromDevice(device);
    if (cntlr == NULL) {
        printf("%s: no service binded!\n", __func__);
        return;
    }

    GpioCntlrRemove(cntlr);

    stm32xx = ToStm32L4xxGpioCntlr(cntlr);//stm32xx其他成员是全局变量，无需动态释放
    Stm32L4xxGpioSelfRlease(stm32xx);
}

struct HdfDriverEntry g_gpioDriverEntry = {
    .moduleVersion = 1,
    .Bind = Stm32L4xxGpioBind,
    .Init = Stm32L4xxGpioInit,
    .Release = Stm32L4xxGpioRelease,
    .moduleName = "GPIO_STM32L4",
};
HDF_INIT(g_gpioDriverEntry);
